package com.lemon.smartsafetynew.ui.activity.video;

import android.content.Context;
import android.content.pm.ActivityInfo;
import android.content.res.Configuration;
import android.graphics.Color;
import android.media.AudioManager;
import android.os.Bundle;
import android.os.PowerManager;
import android.support.annotation.NonNull;
import android.util.Log;
import android.view.Gravity;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

import com.afollestad.materialdialogs.DialogAction;
import com.afollestad.materialdialogs.MaterialDialog;
import com.lemon.android.http.LemonRequestParams;
import com.lemon.smartsafety.R;
import com.lemon.smartsafety.app.Constants;
import com.lemon.smartsafety.app.IApplication;
import com.lemon.smartsafety.http.UrlInfo;
import com.lemon.smartsafety.utils.app.SharedPreferencesServer;
import com.lemon.smartsafetynew.util.constants.KeyConstants;
import com.pili.pldroid.player.AVOptions;
import com.pili.pldroid.player.PLMediaPlayer;
import com.zhy.http.okhttp.OkHttpUtils;
import com.zhy.http.okhttp.callback.StringCallback;

import java.io.IOException;

import butterknife.Bind;
import butterknife.ButterKnife;
import butterknife.OnClick;
import okhttp3.Call;

/**
 * @author Andrew
 */
public class PLMediaPlayerActivity extends VideoPlayerBaseActivity {

    private static final String TAG = PLMediaPlayerActivity.class.getSimpleName();

    @Bind(R.id.back_imageView)
    ImageView backImageView;
    @Bind(R.id.video_name_tv)
    TextView videoNameTv;
    @Bind(R.id.full_screen_imageView)
    ImageView fullScreenImageView;
    @Bind(R.id.frameLayout)
    FrameLayout frameLayout;

    private SurfaceView mSurfaceView;
    private PLMediaPlayer mMediaPlayer;
    private View mLoadingView;
    private AVOptions mAVOptions;

    private int mSurfaceWidth = 0;
    private int mSurfaceHeight = 0;

    private String mVideoPath = null;
    private boolean mIsStopped = false;
    private Toast mToast = null;

    private long mLastUpdateStatTime = 0;

    private boolean mDisableLog = false;

    //add by Andrew.Yin 2018/2/1 begin
    private String keyId = "";
    private String titleName = "";
    private static int videoWidth = 0;
    private static int videoHeight = 0;
    private boolean isPause = false;
    //add by Andrew.Yin 2018/2/1 end

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_media_player);
        ButterKnife.bind(this);

        mVideoPath = getIntent().getStringExtra("videoPath");
        boolean isLiveStreaming = getIntent().getIntExtra("liveStreaming", 1) == 1;

        //add by Andrew.yin 2018/1/30 begin
        keyId = getIntent().getStringExtra("key_id");
        titleName = getIntent().getStringExtra("titleName");
        videoNameTv.setText(titleName);
        videoNameTv.setVisibility(View.GONE);
        //add by Andrew.yin 2018/1/30 end

        mLoadingView = findViewById(R.id.LoadingView);
        mSurfaceView = (SurfaceView) findViewById(R.id.SurfaceView);
        mSurfaceView.getHolder().addCallback(mCallback);

        mSurfaceWidth = getResources().getDisplayMetrics().widthPixels;
        mSurfaceHeight = getResources().getDisplayMetrics().heightPixels;

        mAVOptions = new AVOptions();
        mAVOptions.setInteger(AVOptions.KEY_PREPARE_TIMEOUT, 10 * 1000);
        // 1 -> hw codec enable, 0 -> disable [recommended]
        int codec = getIntent().getIntExtra("mediaCodec", AVOptions.MEDIA_CODEC_SW_DECODE);
        mAVOptions.setInteger(AVOptions.KEY_MEDIACODEC, codec);
        mAVOptions.setInteger(AVOptions.KEY_LIVE_STREAMING, isLiveStreaming ? 1 : 0);
        boolean cache = getIntent().getBooleanExtra("cache", false);

        /* delete by Andrew.yin 这里我们不需要缓存
        if (!isLiveStreaming && cache) {
            mAVOptions.setString(AVOptions.KEY_CACHE_DIR, Config.DEFAULT_CACHE_DIR);
        }
        */

        mDisableLog = getIntent().getBooleanExtra("disable-log", false);
        mAVOptions.setInteger(AVOptions.KEY_LOG_LEVEL, mDisableLog ? 5 : 0);

        AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
        audioManager.requestAudioFocus(null, AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN);

    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        //Log.i("yxy1", "onDestroy");
        release();
        AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
        audioManager.abandonAudioFocus(null);
        cancelWaitDialog();
        cancelDialog();
    }

    @Override
    protected void onResume() {
        super.onResume();
        //Log.i("yxy1", "onResume");
        getVideoPath();
        isPause = false;
    }

    @Override
    protected void onPause() {
        super.onPause();
        //Log.i("yxy1", "onPause");
        release();
        isPause = true;
    }

    /* delete by Andrew.yin 2018/2/1 这里暂时不需要
    public void onClickPlay(View v) {
        if (mIsStopped) {
            prepare();
        } else {
            mMediaPlayer.start();
        }
    }

    public void onClickPause(View v) {
        if (mMediaPlayer != null) {
            mMediaPlayer.pause();
        }
    }

    public void onClickResume(View v) {
        if (mMediaPlayer != null) {
            mMediaPlayer.start();
        }
    }

    public void onClickStop(View v) {
        if (mMediaPlayer != null) {
            mMediaPlayer.stop();
            mMediaPlayer.reset();
        }
        mIsStopped = true;
        mMediaPlayer = null;
    }
    */

    public void releaseWithoutStop() {
        if (mMediaPlayer != null) {
            mMediaPlayer.setDisplay(null);
        }
    }

    /**
     * 释放video资源
     */
    public void release() {
        if (mMediaPlayer != null) {
            mMediaPlayer.stop();
            mMediaPlayer.release();
            mMediaPlayer = null;
        }
    }

    private void prepare() {
        if (mMediaPlayer != null) {
            mMediaPlayer.setDisplay(mSurfaceView.getHolder());
            return;
        }

        try {
            mMediaPlayer = new PLMediaPlayer(this, mAVOptions);
            mMediaPlayer.setDebugLoggingEnabled(true);
            mMediaPlayer.setLooping(getIntent().getBooleanExtra("loop", false));
            mMediaPlayer.setOnPreparedListener(mOnPreparedListener);
            mMediaPlayer.setOnVideoSizeChangedListener(mOnVideoSizeChangedListener);
            mMediaPlayer.setOnCompletionListener(mOnCompletionListener);
            mMediaPlayer.setOnErrorListener(mOnErrorListener);
            mMediaPlayer.setOnInfoListener(mOnInfoListener);
            mMediaPlayer.setOnBufferingUpdateListener(mOnBufferingUpdateListener);
            mMediaPlayer.setDebugLoggingEnabled(!mDisableLog);
            // set replay if completed
            // mMediaPlayer.setLooping(true);
            mMediaPlayer.setWakeMode(getApplicationContext(), PowerManager.PARTIAL_WAKE_LOCK);
            mMediaPlayer.setDataSource(mVideoPath);
            mMediaPlayer.setDisplay(mSurfaceView.getHolder());
            mMediaPlayer.prepareAsync();
        } catch (UnsatisfiedLinkError e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private SurfaceHolder.Callback mCallback = new SurfaceHolder.Callback() {

        @Override
        public void surfaceCreated(SurfaceHolder holder) {
            //prepare(); disable by Andrew.yin 2018/2/1 这里我们不需要进来就显示

        }

        @Override
        public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {

        }

        @Override
        public void surfaceDestroyed(SurfaceHolder holder) {
            //release();              //释放资源
            //releaseWithoutStop();   //释放Hold
        }
    };

    private PLMediaPlayer.OnVideoSizeChangedListener mOnVideoSizeChangedListener = new PLMediaPlayer.OnVideoSizeChangedListener() {
        public void onVideoSizeChanged(PLMediaPlayer mp, int width, int height) {
            Log.i(TAG, "onVideoSizeChanged: width = " + width + ", height = " + height);
            // resize the display window to fit the screen
            if (width != 0 && height != 0) {

                videoWidth = width;
                videoHeight = height;

                int screenNum = getResources().getConfiguration().orientation;
                if (screenNum == 2) { // 2为横屏
                    FrameLayout.LayoutParams layout = new FrameLayout.LayoutParams(mSurfaceHeight, mSurfaceWidth);
                    layout.gravity = Gravity.CENTER;
                    mSurfaceView.setLayoutParams(layout);
                } else {
                    float ratioW = (float) width / (float) mSurfaceWidth;
                    float ratioH = (float) height / (float) mSurfaceHeight;
                    float ratio = Math.max(ratioW, ratioH);
                    width = (int) Math.ceil((float) width / ratio);
                    height = (int) Math.ceil((float) height / ratio);
                    FrameLayout.LayoutParams layout = new FrameLayout.LayoutParams(width, height);
                    layout.gravity = Gravity.CENTER;
                    mSurfaceView.setLayoutParams(layout);
                }

            }
        }
    };

    private PLMediaPlayer.OnPreparedListener mOnPreparedListener = new PLMediaPlayer.OnPreparedListener() {
        @Override
        public void onPrepared(PLMediaPlayer mp, int preparedTime) {
            Log.i(TAG, "On Prepared ! prepared time = " + preparedTime + " ms");
            mMediaPlayer.start();
            mIsStopped = false;
        }
    };

    private PLMediaPlayer.OnInfoListener mOnInfoListener = new PLMediaPlayer.OnInfoListener() {
        @Override
        public boolean onInfo(PLMediaPlayer mp, int what, int extra) {
            //Log.i(TAG, "OnInfo, what = " + what + ", extra = " + extra);
            switch (what) {
                case PLMediaPlayer.MEDIA_INFO_BUFFERING_START:
                    mLoadingView.setVisibility(View.VISIBLE);
                    break;
                case PLMediaPlayer.MEDIA_INFO_BUFFERING_END:
                    mLoadingView.setVisibility(View.GONE);
                    break;
                case PLMediaPlayer.MEDIA_INFO_VIDEO_RENDERING_START:
                    mLoadingView.setVisibility(View.GONE);
                    mIsStopped = false;
                    //showToastTips("first video render time: " + extra + "ms");
                    break;
                case PLMediaPlayer.MEDIA_INFO_VIDEO_GOP_TIME:
                    Log.i(TAG, "Gop Time: " + extra);
                    break;
                case PLMediaPlayer.MEDIA_INFO_AUDIO_RENDERING_START:
                    mLoadingView.setVisibility(View.GONE);
                    break;
                case PLMediaPlayer.MEDIA_INFO_SWITCHING_SW_DECODE:
                    Log.i(TAG, "Hardware decoding failure, switching software decoding!");
                    break;
                case PLMediaPlayer.MEDIA_INFO_METADATA:
                    Log.i(TAG, mMediaPlayer.getMetadata().toString());
                    break;
                case PLMediaPlayer.MEDIA_INFO_VIDEO_BITRATE:
                case PLMediaPlayer.MEDIA_INFO_VIDEO_FPS:

                    break;
                case PLMediaPlayer.MEDIA_INFO_CONNECTED:
                    Log.i(TAG, "Connected !");
                    break;
                case PLMediaPlayer.MEDIA_INFO_VIDEO_ROTATION_CHANGED:
                    Log.i(TAG, "Rotation changed: " + extra);
                default:
                    break;
            }
            return true;
        }
    };

    private PLMediaPlayer.OnBufferingUpdateListener mOnBufferingUpdateListener = new PLMediaPlayer.OnBufferingUpdateListener() {
        @Override
        public void onBufferingUpdate(PLMediaPlayer mp, int percent) {
            Log.d(TAG, "onBufferingUpdate: " + percent + "%");
            long current = System.currentTimeMillis();
            if (current - mLastUpdateStatTime > 3000) {
                mLastUpdateStatTime = current;

            }
        }
    };

    /**
     * Listen the event of playing complete
     * For playing local file, it's called when reading the file EOF
     * For playing network stream, it's called when the buffered bytes played over
     * <p>
     * If setLooping(true) is called, the player will restart automatically
     * And ｀onCompletion｀ will not be called
     */
    private PLMediaPlayer.OnCompletionListener mOnCompletionListener = new PLMediaPlayer.OnCompletionListener() {
        @Override
        public void onCompletion(PLMediaPlayer mp) {
            Log.d(TAG, "Play Completed !");
            showToastTips("播放完毕!");
            finish();
        }
    };

    private PLMediaPlayer.OnErrorListener mOnErrorListener = new PLMediaPlayer.OnErrorListener() {
        @Override
        public boolean onError(PLMediaPlayer mp, int errorCode) {
            Log.e(TAG, "Error happened, errorCode = " + errorCode);
            switch (errorCode) {
                case PLMediaPlayer.ERROR_CODE_IO_ERROR:
                    /**
                     * SDK will do reconnecting automatically
                     */
                    if (!isPause) {
                        showToastTips("网络异常!");
                    }
                    return false;
                case PLMediaPlayer.ERROR_CODE_OPEN_FAILED:
                    showToastTips("播放器模块打开失败，请彻底退出应用重试!");
                    break;
                case PLMediaPlayer.ERROR_CODE_SEEK_FAILED:
                    showToastTips("拖动失败!");
                    break;
                default:
                    showToastTips("未知错误!");
                    break;
            }
            finish();
            return true;
        }
    };

    private void showToastTips(final String tips) {
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                if (mToast != null) {
                    mToast.cancel();
                }
                mToast = Toast.makeText(PLMediaPlayerActivity.this, tips, Toast.LENGTH_SHORT);
                mToast.show();
            }
        });
    }

    // ============== 请求视频地址 begin ================

    private MaterialDialog waitDialog;
    private MaterialDialog retryDialog;

    private void waitingDialog() {
        waitDialog = new MaterialDialog.Builder(PLMediaPlayerActivity.this)
                .content(R.string.please_wait)
                .progress(true, 0)
                .cancelable(false)
                .show();
    }

    private void confirmDialog(String remark) {
        retryDialog = new MaterialDialog.Builder(this)
                .title("提示")
                .content(remark)
                .contentColor(Color.parseColor("#FFFF0000"))
                .positiveText("确认")
                .onPositive(new MaterialDialog.SingleButtonCallback() {
                    @Override
                    public void onClick(@NonNull MaterialDialog dialog, @NonNull DialogAction which) {
                        PLMediaPlayerActivity.this.finish();
                    }
                })
                .negativeText("再试一次")
                .onNegative(new MaterialDialog.SingleButtonCallback() {
                    @Override
                    public void onClick(@NonNull MaterialDialog dialog, @NonNull DialogAction which) {
                        getVideoPath();
                    }
                })
                .cancelable(false)
                .show();
    }

    private void cancelWaitDialog() {

        if (waitDialog != null && waitDialog.isShowing()) {
            waitDialog.dismiss();
            waitDialog = null;
        }
    }

    private void cancelDialog() {

        if (retryDialog != null && retryDialog.isShowing()) {
            retryDialog.dismiss();
            retryDialog = null;
        }
    }

    /**
     * 获取播放码流
     */
    private void getVideoPath() {

        waitingDialog();

        LemonRequestParams params = new LemonRequestParams("");
        params.put("key_id", keyId);

        SharedPreferencesServer mSharedPreferencesServer = new SharedPreferencesServer(IApplication.context());
        String serverUrl = mSharedPreferencesServer.getRequestUrl(UrlInfo.GET_MONITOR_VIDEO_URL, Constants.VIDEO_SERVER);
        //String serverUrl = "http://58.215.171.233:18080/acloud_new/dai/startToPlayForMoblie.json";

        OkHttpUtils.post()
                .url(serverUrl)
                .params(params)
                .build().execute(new StringCallback() {

            @Override
            public void onError(Call call, Exception e) {
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        cancelWaitDialog();
                        confirmDialog("错误：获取视频资源失败");
                    }
                });
            }

            @Override
            public void onResponse(String response) {
                Log.e("返回onResponse", KeyConstants.URL_GET_MONITOR_VIDEO_URL + " " + response);

                mVideoPath = response;

                if ("".equals(response)) {

                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            cancelWaitDialog();
                            confirmDialog("错误：获取视频资源失败");
                        }
                    });

                } else {

                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            cancelWaitDialog();
                            prepare();
                        }
                    });

                }

            }
        });

    }

    @OnClick({R.id.back_imageView, R.id.full_screen_imageView})
    public void onViewClicked(View view) {
        switch (view.getId()) {
            case R.id.back_imageView:
                back();
                break;
            case R.id.full_screen_imageView:
                fullScreenImageView.setVisibility(View.GONE);
                setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
                break;
        }
    }

    private void back() {
        int screenNum = getResources().getConfiguration().orientation;
        if (screenNum == 1) { // 1为竖屏
            PLMediaPlayerActivity.this.finish();
        } else {
            setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
            fullScreenImageView.setVisibility(View.VISIBLE);
        }
    }

    @Override
    public void onBackPressed() {
        int screenNum = getResources().getConfiguration().orientation;
        if (screenNum == 1) {
            super.onBackPressed();
        } else {
            setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
            fullScreenImageView.setVisibility(View.VISIBLE);
        }
    }


    @Override
    public void onConfigurationChanged(Configuration newConfig) {

        if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
            //Log.e("yxy", "横屏");
            /*
            float ratioW = (float) videoWidth / (float) mSurfaceHeight;
            float ratioH = (float) videoWidth / (float) mSurfaceWidth;
            float ratio = Math.max(ratioW, ratioH);
            int width = (int) Math.ceil((float) videoWidth / ratio);
            int height = (int) Math.ceil((float) videoWidth / ratio);
            FrameLayout.LayoutParams layout = new FrameLayout.LayoutParams(width, height);
            layout.gravity = Gravity.CENTER;
            mSurfaceView.setLayoutParams(layout);
            */

            FrameLayout.LayoutParams layout = new FrameLayout.LayoutParams(mSurfaceHeight, mSurfaceWidth);
            layout.gravity = Gravity.CENTER;
            mSurfaceView.setLayoutParams(layout);

        } else {

            //Log.e("yxy", "竖屏");
            float ratioW = (float) videoWidth / (float) mSurfaceWidth;
            float ratioH = (float) videoHeight / (float) mSurfaceHeight;
            float ratio = Math.max(ratioW, ratioH);
            int width = (int) Math.ceil((float) videoWidth / ratio);
            int height = (int) Math.ceil((float) videoHeight / ratio);
            FrameLayout.LayoutParams layout = new FrameLayout.LayoutParams(width, height);
            layout.gravity = Gravity.CENTER;
            mSurfaceView.setLayoutParams(layout);
        }
        super.onConfigurationChanged(newConfig);
    }
}
